package com.dean.ui;

import com.dean.exception.DeanRuntimeException;

import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author dean
 * @version 1.0
 * @description: TODO
 * @date 2024/8/5 14:23
 */
public class DeanFormUIUtils {
    // 当前面板
    private JPanel panel;

    private GridBagLayout layout;

    private GridBagConstraints constraints;

    private Double balanceWeighty = 1.0;

    private static final Integer ALL_COL_NUMS = 10;
    private static final Integer LABEL_COL_NUMS = 1;

    private static final Integer TEXT_AREA_ROW_NUMS = 5;

    private static final Integer TEXT_COL_NUMS = 4;

    private static final Integer LONG_TEXT_COL_NUMS = 9;

    private static final Double ALL_COL_SCALE = 1.0;
    private static final Double LABEL_COL_SCALE = 0.1;

    private static final Double TEXT_COL_SCALE = 0.5;

    private static final Double LONG_TEXT_COL_SCALE = 0.9;

    private static final Double TABLE_ROW_SCALE = 0.5;



    // 记录当前组件的行
    private int row = 0;
    // 记录当前组件所在行的列
    private int col = 0;
    // 默认列占比
    private static final Integer DEFAULT_COL_SPAN = 1;

    // 默认行占比
    private static final Integer DEFAULT_ROW_SPAN = 1;


    private static final Double DEFAULT_ROW_SCALE = 0.01;

    public JPanel buildPanel(){
        this.panel = new JPanel();
        // 布局方式
        this.layout = new GridBagLayout();
        this.panel.setLayout(layout);
        this.constraints = new GridBagConstraints();
        this.constraints.fill = GridBagConstraints.BOTH;
        return this.panel;
    }

    public void finishCreate(){
        if(balanceWeighty == 0){
            return;
        }
        calRowAndCol(ALL_COL_NUMS);
        JLabel blankRow = new JLabel();
        setConstraints(blankRow,ALL_COL_SCALE,ALL_COL_NUMS,balanceWeighty);
    }

    private JLabel createLabel(String labelText){
        JLabel label = new JLabel(labelText,JLabel.RIGHT);
        label.setName("LABEL_"+labelText);
        setLabelConstraints(label);
        return label;
    }

    public JButton createButton(String buttonText){
        JButton button = new JButton(buttonText);
        button.setName("BTN_"+buttonText);
        setButtonConstraints(button);
        return button;
    }

    public JTextArea createTextArea(String labelText, boolean allRow){
        if(allRow && this.col > 0){
            calRowAndCol(ALL_COL_NUMS);
        }
        createLabel(labelText);
        JTextArea textArea = new JTextArea();
        textArea.setName("TEXT_AREA_"+labelText);
        setTextAreaConstraints(textArea,allRow);
        textArea.setRows(5);
        return textArea;
    }
    public JTextField createText(String labelText){
        return createText(labelText,false);
    }

    public JTextField createText(String labelText, boolean allRow){
        if(allRow && this.col > 0){
            calRowAndCol(ALL_COL_NUMS);
        }
        createLabel(labelText);
        JTextField textField = new JTextField();
        textField.setName("TEXT_"+labelText);
        setTextConstraints(textField,allRow);
        return textField;
    }

    public JTable createTable(){
        return createTable(null);
    }

    public JTable createTable(boolean allBalanceHeight){
        return createTable(allBalanceHeight,null);
    }

    public JTable createTable(PageCallback callback){
        return createTable(false,callback);
    }

    public JTable createTable(boolean allBalanceHeight,PageCallback callback){
        if(col > 0){
            calRowAndCol(ALL_COL_NUMS);
        }
        JTable table = new JTable();
        table.setName("TABLE_"+"DEFAULT");
        setTableConstraints(table,allBalanceHeight);
        if(callback != null){
            // 分页组件
            createPage(callback);
        }
        return table;
    }

    public JComboBox createComboBox(Object [] items){
        JComboBox comboBox = new JComboBox(items);
        setConstraints(comboBox,LABEL_COL_SCALE,LABEL_COL_NUMS);
        return comboBox;
    }

    public PageTableComponent createSpinner(){
        JSpinner spinner = new JSpinner();
        SpinnerModel model = new SpinnerNumberModel(1,1,2000,1);
        spinner.setModel(model);
        JSpinner.NumberEditor editor = new JSpinner.NumberEditor(spinner,"0");
        spinner.setEditor(editor);
        JFormattedTextField textField = ((JSpinner.NumberEditor) spinner.getEditor()).getTextField();
        textField.setEditable(true);
        DefaultFormatterFactory factory = (DefaultFormatterFactory)textField.getFormatterFactory();
        NumberFormatter formatter = (NumberFormatter)factory.getDefaultFormatter();
        formatter.setAllowsInvalid(false);
        spinner.setName("Spinner_Default");
        setConstraints(spinner,LABEL_COL_SCALE,LABEL_COL_NUMS);
        PageTableComponent pageComponent = new PageTableComponent();
        pageComponent.setSpinner(spinner);
        pageComponent.setTextField(textField);
        return pageComponent;

    }

    private Integer getNumFromStr(String content){
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(content);
        if(matcher.find()){
          return Integer.parseInt(matcher.group());
        }
        return null;
    }


    public PageTableComponent createPage(PageCallback callback){
        JButton firstPageBtn = createButton("首页");
        JButton lastPageBtn = createButton("上一页");
        createLabel("第");
        PageTableComponent pageComponent = createSpinner();
        JSpinner spinner = pageComponent.getSpinner();
        JFormattedTextField textField = pageComponent.getTextField();
        JLabel tatalPageInfo = createLabel("页,共页");
        JComboBox comboBox = createComboBox(new Integer[]{100,200,500,1000});
        JLabel recordInfoLabel = createLabel("条/页,共条");
        JButton nextPageBtn = createButton("下一页");
        JButton endPageBtn = createButton("尾页");
        firstPageBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int currPage = Integer.parseInt(spinner.getValue().toString());
                if(currPage == 1){
                    return;
                }
                currPage = 1;
                spinner.setValue(currPage);
                doPage(spinner,comboBox,callback,tatalPageInfo,recordInfoLabel);
            }
        });
        lastPageBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int currPage = Integer.parseInt(spinner.getValue().toString());
                if(currPage == 1){
                    return;
                }
                currPage = currPage -1;
                spinner.setValue(currPage);
                doPage(spinner,comboBox,callback,tatalPageInfo,recordInfoLabel);
            }
        });
        nextPageBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int currPage = Integer.parseInt(spinner.getValue().toString());
                Integer totalPage = getNumFromStr(tatalPageInfo.getText());
                if(totalPage == null || totalPage.equals(currPage)){
                    return;
                }
                currPage = currPage + 1;
                spinner.setValue(currPage);
                doPage(spinner,comboBox,callback,tatalPageInfo,recordInfoLabel);
            }
        });
        endPageBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int currPage = Integer.parseInt(spinner.getValue().toString());
                Integer totalPage = getNumFromStr(tatalPageInfo.getText());
                if(totalPage == null || totalPage.equals(currPage)){
                    return;
                }
                currPage = totalPage;
                spinner.setValue(currPage);
                doPage(spinner,comboBox,callback,tatalPageInfo,recordInfoLabel);
            }
        });
        textField.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {

            }

            @Override
            public void keyPressed(KeyEvent e) {

            }

            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_ENTER){
                    doPage(spinner,comboBox,callback,tatalPageInfo,recordInfoLabel);
                }

            }
        });
        pageComponent.setFirstPageBtn(firstPageBtn);
        return pageComponent;

    }

    private PageInfo doPage(JSpinner pageNumSpinner, JComboBox pageSizeBox, PageCallback callback,JLabel tatalPageInfo,JLabel recordInfoLabel){
        int pageSize = Integer.parseInt(pageSizeBox.getSelectedItem().toString()) ;
        int pageNum = Integer.parseInt(pageNumSpinner.getValue().toString()) ;
        PageInfo pageInfo = callback.doPag(pageSize,pageNum);
        tatalPageInfo.setText(String.format("页,共%d页",pageInfo.getTotalPage()));
        tatalPageInfo.setHorizontalAlignment(JLabel.LEFT);
        recordInfoLabel.setText(String.format("条/页,共%d条",pageInfo.getTotal()));
        recordInfoLabel.setHorizontalAlignment(JLabel.LEFT);
        return pageInfo;
    }

    public void setTableConstraints(JTable table,boolean allBalanceHeight){
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setName(table.getName());
        if(allBalanceHeight){
            setConstraints(scrollPane,ALL_COL_SCALE,ALL_COL_NUMS,balanceWeighty);
        }else{
            setConstraints(scrollPane,ALL_COL_SCALE,ALL_COL_NUMS,TABLE_ROW_SCALE);
        }
        scrollPane.setViewportView(table);
    }

    public void setButtonConstraints(JButton button){
       setConstraints(button,LABEL_COL_SCALE,LABEL_COL_NUMS);
    }

    public void setTextAreaConstraints(JTextArea textArea, boolean allRow){
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setName(textArea.getName());
        if(allRow){
            setConstraints(scrollPane,LONG_TEXT_COL_SCALE,LONG_TEXT_COL_NUMS);
        }else{
            setConstraints(scrollPane,TEXT_COL_SCALE,TEXT_COL_NUMS);
        }
        scrollPane.setViewportView(textArea);
    }

    public void setTextConstraints(JTextField textField, boolean allRow){
        if(allRow){
            setConstraints(textField,LONG_TEXT_COL_SCALE,LONG_TEXT_COL_NUMS);
        }else{
            setConstraints(textField,TEXT_COL_SCALE,TEXT_COL_NUMS);
        }
    }

    public void setLabelConstraints(JLabel label){
        setConstraints(label,LABEL_COL_SCALE, DEFAULT_COL_SPAN);
    }

    public void setConstraints(Component component, Double weightx, int colSpan){
        setConstraints(component,weightx,colSpan,DEFAULT_ROW_SCALE);
//        // 坐标左下角 X轴
//        constraints.gridx = col;
//        // 坐标左下角 Y轴
//        constraints.gridy = row;
//        // 所占列数
//        constraints.gridwidth = colSpan;
//        // 所占行数
//        constraints.gridheight = DEFAULT_ROW_SPAN;
//        // 列在一行中的占比 只有1，3，4
//        constraints.weightx = weightx;
//        // 行在整个布局中站的比例
//        constraints.weighty = DEFAULT_ROW_SCALE;
//        System.out.println("component:"+ component.getName()+",weightx："+ constraints.weightx+",weighty:"+constraints.weighty+",col:"+col+",colSpan:"+colSpan);
//        layout.setConstraints(component, constraints);
//        this.panel.add(component);
//        this.calRowAndCol(DEFAULT_ROW_SPAN,colSpan);
    }

    public void setConstraints(Component component, Double weightx, int colSpan,Double weighty){
        // 坐标左下角 X轴
        constraints.gridx = col;
        // 坐标左下角 Y轴
        constraints.gridy = row;
        // 所占列数
        constraints.gridwidth = colSpan;
        // 所占行数
        constraints.gridheight = DEFAULT_ROW_SPAN;
        // 列在一行中的占比 只有1，3，4
        constraints.weightx = weightx;
        // 行在整个布局中站的比例
        constraints.weighty = weighty;
        System.out.println("component:"+ component.getName()+",weightx："+ constraints.weightx+",weighty:"+constraints.weighty+",col:"+col+",colSpan:"+colSpan);
        layout.setConstraints(component, constraints);
        this.panel.add(component);
        this.calRowAndCol(DEFAULT_ROW_SPAN,colSpan);
    }


    public void calRowAndCol(){
        calRowAndCol(DEFAULT_ROW_SPAN,DEFAULT_COL_SPAN);
    }

    public void calRowAndCol(int colSpan){
        calRowAndCol(DEFAULT_ROW_SPAN,colSpan);
    }


    public void calRowAndCol(int rowSpan,int colSpan){
//        System.out.println("before:::row:"+this.row+",col:"+this.col);
        this.col = this.col + colSpan;
        if(this.col > LONG_TEXT_COL_NUMS){
            this.col = 0;
            this.row = this.row + rowSpan;
        }
        balanceWeighty = balanceWeighty - constraints.weighty;
//        System.out.println("after:::row:"+this.row+",col:"+this.col);
    }

}
